package com.smileus.integration.caller.impl;

import java.net.ConnectException;
import java.util.HashMap;
import java.util.Map;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;

import com.alibaba.fastjson.JSONArray;
import com.smileus.common.CallInfo;
import com.smileus.common.Env;
import com.smileus.entity.IntegrationLogs;
import com.smileus.entity.ServiceInfo;
import com.smileus.entity.ServiceRouter;
import com.smileus.integration.caller.AbstractCaller;
import com.smileus.integration.caller.Caller;
import com.smileus.integration.security.SecurityChecker;
import com.smileus.service.IntegrationLogsService;
import com.smileus.service.ServiceInfoService;

public class CxfSyncCaller extends AbstractCaller implements Caller {
	private static ServiceInfoService serviceInfoService = Env.getBean("serviceInfoService", ServiceInfoService.class);
	private static ServiceRouter cfgRouter = clusterService.getCurtServiceRouter();
	private static Map<String, Client> clientMap = new HashMap<String, Client>();

	// 参数默认转为JSONArry格式字符串
	public String call(String serviceId, Object... param) {
		String jsonArray = null;
		String result = null;
		String url = null;
		IntegrationLogs logs = new IntegrationLogs();
		CallInfo callInfo = clusterService.getCallInfo(serviceId);
		ServiceInfo serviceInfo = serviceInfoService.getServiceInfo(callInfo.getSysDomain(), callInfo.getService());
		SecurityChecker securityChecker = Env.getBean(serviceInfo.getControlBeanId(), SecurityChecker.class);
		if (securityChecker == null || securityChecker.check().isPass() == false) {
			throw new RuntimeException("安全检查不通过，请检查！");
		}
		logs.setServiceId(serviceId);
		logs.setFromSys(cfgRouter.getSysDomain());
		logs.setFromHost(cfgRouter.getServiceHost());
		if (param == null) {
			jsonArray = "[]";
		} else {
			jsonArray = JSONArray.toJSONString(param);
		}
		logs.setInParam(jsonArray);
		try {
			url = getURL(serviceId);
			logs.setToSys(callInfo.getSysDomain());
			logs.setToHost(toTargetHost(url));
			Client client = null;
			// 将client静态化存储，有没有问题？
			if (clientMap.containsKey(url)) {
				client = clientMap.get(url);
			} else {
				client = JaxWsDynamicClientFactory.newInstance().createClient(url);
				clientMap.put(url, client);
			}
			Object[] objects = client.invoke("doService", getCallInfo(serviceId).getService(), jsonArray);
			result = objects[0].toString();
			logs.setSuccess(1);
			logs.setOutParam(result);
		} catch (ConnectException e) {
			// RPC调用异常处理
			// TODO :
			/**
			 **异常情况下保障高可用： 1.可以尝试调用其他机器的服务 2.如果超过规定次数，远程启动备用服务器 3.短信、邮件通知系统owner
			 */
			if (clusterService.incrementAndCheck(url)) {
				// TODO：启用备用机器
				ServiceRouter sRouter = clusterService.getServiceRouterByPubAddress(url);
				if (sRouter.getServiceStatus() == 1) {
					sRouter.setServiceStatus(-1);// 设置为不可用状态
					clusterService.saveOrUpdateServiceRouter(sRouter);
				}
				clusterService.clusterRefresh();
				clusterService.sendMessage(sRouter);// 短信邮件通知
			}
			// 记录异常日志
			logs.setSuccess(-1);
			logs.setOutParam(e.getMessage());
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		IntegrationLogsService.saveLogs(logs);
		return result;
	}
}
